<template>
  <div id="detail">
    <detail-nav-bar class="detail-nav" @titleClick="titleClick" ref="nva"></detail-nav-bar>
    <scroll class="content" :probe-type="3" :pull-up-load="true" ref="scroll" 
    @scroll="detailScroll" @pullingUp="loadMoer" > 
      <detail-swiper :top-images="topImages"></detail-swiper>
      <detail-base-info :goods="goods"></detail-base-info>
      <detail-shop-info :shop="shop"></detail-shop-info>
      <detail-goods-info :detail-info="detailInfo" @imageLoad="imageLoad"></detail-goods-info>
      <detail-param-info ref="params" :param-info="paramInfo"></detail-param-info>
      <detail-comment-info ref="comment" :comment-info="commentInfo"></detail-comment-info>
      <goods-list ref="recommend" :goods="recommends"></goods-list>     
    </scroll>
    <!--要监听组件的事件，必须加native-->
    <back-top @click.native="backClick" v-show="isShowBackTop"></back-top>
    <detail-bottom-bar @addCart="addCartTo"></detail-bottom-bar>    
  </div>
</template>

<script>
//导入模板 
import DetailNavBar from './childComps/DetailNavBar.vue'
import Scroll from "components/common/scroll/Scroll" //滚动组件
import DetailSwiper from './childComps/DetailSwiper.vue'
import DetailBaseInfo from './childComps/DetailBaseInfo.vue'
import DetailShopInfo from './childComps/DetailShopInfo.vue'
import DetailGoodsInfo from "./childComps/DetailGoodsInfo" //商品详细信息
import DetailParamInfo from "./childComps/DetailParamInfo" //商品参数信息
import DetailCommentInfo from "./childComps/DetailCommentInfo" //商品评论信息
import GoodsList from "components/content/goods/GoodsList" //商品列表
import DetailBottomBar from "./childComps/DetailBottomBar" //底部工具栏
//导入js组件
import {getDetail,Goods,Shop,GoodsParam,getRecommend} from 'network/detail.js'
//防抖函数
//当一个函数执行次数太频繁，消耗资源，比如图片加载以后重置滚动组件的高度
import { debounce } from "common/utils"

//导入混入
import { itemListenerMixin, backTopMixin } from "common/mixin"
//导入vuex里面的actions方法
import { mapActions} from 'vuex'

export default {
  name: "Detail",
  components: {
    DetailNavBar,
    DetailSwiper,
    DetailBaseInfo,
    DetailShopInfo,
    Scroll,
    DetailGoodsInfo,
    DetailParamInfo,
    DetailCommentInfo,
    GoodsList,
    DetailBottomBar
  },
  data() {
    return {
      iid: null,
      topImages: [],
      goods: {},
      shop: {},
      detailInfo: {},
      paramInfo: {},
      commentInfo: {},
      recommends: [],
      themeTopY: [], //顶部导航的跳转Y坐标
      getThemeTopY: null, //顶部导航跳转的图片加载防抖方法
      currentIndex: 0//记录滚动的区域
    }
  },
  mixins:[itemListenerMixin, backTopMixin],
  //在模板渲染成html后调用，通常是初始化页面完成后，再对html的dom节点进行一些需要的操作。
  mounted() {
    // //利用防抖执行图片加载回调函数
    // const refresh = debounce(this.$refs.scroll.refresh,200)
    // //监听GoogsListItem组件发送的事件总线，用于解决滚动组件高度的问题
    // //监听GoogsListItem组件图片加载完成的事件
    // //保存方法
    // this.itemImgListener = () => {
    //   //this.$refs.scroll.refresh()
    //   refresh()
    // }
    // this.$bus.$on('itemImageLoad', this.itemImgListener)
    //利用混入注入 以上代码注销
    this.$bus.$on('detailItemImageLoad', this.detailItemImageLoad)
    
  },
  // 只有data里的变量改变并且要在页面重新渲染完成之后,才会进updated生命周期，
  // 只改变data里的值但是没有再页面上渲染该值的话并不会触发updated方法。
  updated() {
    
  },
  //created 组件创建完成后调用
  created() {
    //获取路由传入的iid
    this.iid = this.$route.params.iid
    //根据ID网络请求数据
    getDetail(this.iid).then(res => {
      //获取顶部图片轮播图数据
      const data = res.result
      this.topImages = data.itemInfo.topImages
      //获取商品信息
      this.goods = new Goods(data.itemInfo,data.columns,data.shopInfo.services)
      //获取店铺信息
      this.shop = new Shop(data.shopInfo)
      //获取商品的详情数据
      this.detailInfo = data.detailInfo
      //获取商品参数
      this.paramInfo = new GoodsParam(data.itemParams.info,data.itemParams.rule)
      //获取评论信息
      if(data.rate.cRate !== 0) {
        this.commentInfo = data.rate.list[0]
      }

      //防抖方法赋值
      this.getThemeTopY = debounce( () => {
        this.themeTopY = []
        //获取各组件的Y坐标
        this.themeTopY.push(0)//商品
        this.themeTopY.push(this.$refs.params.$el.offsetTop)//参数
        this.themeTopY.push(this.$refs.comment.$el.offsetTop)//评论
        this.themeTopY.push(this.$refs.recommend.$el.offsetTop)//推荐
        this.themeTopY.push(Number.MAX_VALUE) //插入一个最大值
      })

// 在Vue生命周期的created()钩子函数进行的DOM操作一定要放在Vue.nextTick()的回调函数中
// 在created()钩子函数执行的时候DOM 其实并未进行任何渲染，而此时进行DOM操作无异于徒劳，
// 所以此处一定要将DOM操作的js代码放进Vue.nextTick()的回调函数中。与之对应的就是mounted()钩子函数，
// 因为该钩子函数执行时所有的DOM挂载和渲染都已完成，此时在该钩子函数中进行任何DOM操作都不会有问题 。
// 在数据变化后要执行的某个操作，而这个操作需要使用随数据改变而改变的DOM结构的时候，
// 这个操作都应该放进Vue.nextTick()的回调函数中。


      this.$nextTick( () => {
        
      })
    }).catch(err => {
      console.log(err)
    })

    //请求推荐数据
    getRecommend().then(res => {
      this.recommends = res.data.list
    }).catch(err => {
      console.log(err)
    })
  },
  methods: {
    //导入vuex 里面的 actions方法
    ...mapActions(["addCart"]),
    //刷新滚动组件高度
    imageLoad() {
      this.$refs.scroll.refresh()  
      this.getThemeTopY()
    },
    //子组件 滚动组件传送滚动坐标
    detailScroll(position) {
      //当坐标y轴大于1000的时候显示返回顶部按钮
      // this.isShowBackTop = -position.y >1000
      //决定tabControl 是否吸顶 (postition: fixed)
      // this.isTabFixed = (-position.y) > this.tabOffsetTop

      //或者Y轴
      const positionY = -position.y
      //获得到的Y值和主题中的值对比
      let length = this.themeTopY.length
      for(let i =0; i <length-1; i++) {
        //常规写法

        // if(this.currentIndex !== i && ((i<length -1 && positionY > this.themeTopY[i] && positionY < this.themeTopY[i+1] ) 
        // || (i === length -1 && positionY > this.themeTopY[i]))) {
        //   this.currentIndex = i
        //   this.$refs.nva.currentIndex = i
        // }

        //简化写法
        if(this.currentIndex !== i && (positionY >= this.themeTopY[i] && positionY < this.themeTopY[i+1])) {
          this.currentIndex = i
          this.$refs.nva.currentIndex = i
        }
      }

      //当坐标y轴大于1000的时候显示返回顶部按钮
      this.listenShowBackTo(position)     
    },
    //上拉加载更多
    loadMoer() {
      // this.getHomeGoodsMthods(this.currentType)
    },
    //头部导航传递点击事件
    titleClick(index) {
      this.$refs.scroll.scrollTo(0,-this.themeTopY[index],200)
    },
    detailItemImageLoad() {
      this.getThemeTopY()
    },
    //添加购物车事件
    addCartTo() {
      //获取购物车需要展示的信息
      const product = {}
      product.image = this.topImages[0]
      product.title = this.goods.title
      product.desc = this.goods.desc
      product.price = this.goods.realPrice
      product.iid = this.iid
      //将商品添加到购物车
      //this.$store.commit("addCart",product) 这种写法不适合，直接在组件操作commit
      //此种方法是原始的调用方式
      // this.$store.dispatch("addCart",product).then(res => {
      //   console.log(res)
      // })
      //此种方法是把vuex的 action 映射到了本组件
      this.addCart(product).then(res => {
        this.$toast.show(res)
        console.log(res)
      })
      
    }
  },
  //组件销毁
  destroyed() {
    this.$bus.$off('itemImageLoad', this.itemImgListener)
    this.$bus.$off('detailItemImageLoad', this.detailItemImageLoad)
  }
}
</script>

<style scoped>
#detail {
  position: relative;
  z-index: 9;
  background-color: #fff;
  height: 100vh;
}
.content {
  height: calc(100% - 44px - 49px);
}
.detail-nav {
  position: relative;
  z-index: 9;
  background-color: #fff;
}
</style>
